package com.esig.socket;

import com.esig.Model.PlayerOther;
import com.esig.View.GameFrame;

import javax.swing.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;

public class ClientUI2 extends JFrame {
    ChatClient1 client;

    public ChatClient1 getClient() {
        return client;
    }

    public void setClient(ChatClient1 client) {
        this.client = client;
    }

    public ClientUI2(String ip, GameFrame gameFrame) {

        //client = new ChatClient1("127.0.0.1", gameFrame);
        client = new ChatClient1(ip, gameFrame);

        //构造方法 其中ipArea.getText().trim()是上面的127.0.0.1 设置UI，是为了区分多个客户端，我要是做游戏的话，就是通过 玩家对象 区分

        client.start(); //启动线程 这个线程和服务器端的一样原理
        ClientUI2.this.setClient(client);  //设置ChatClient1 类
        client.sendMsg("进入房间");  //客户端发送信息给服务器端


    }

    /**
     * 联机模式菜单选择的按下按键操作
     */
    public void OnlineKeyPressed(int keyCode) {
        System.out.println(keyCode);
        client.sendMsg(keyCode + ",press");
    }

    /**
     * 联机模式菜单选择的松开按键操作
     */
    public void OnlineKeyReleased(int keyCode) {
        client.sendMsg(keyCode + ",released");
    }


}

class ChatClient1 extends Thread {
    Socket sc;
    BufferedReader in;
    PrintWriter out;
    GameFrame gameFrame;
    Integer index = 0; //获取对应下标

//    PlayerOther playerOther;

    public ChatClient1(String ip, GameFrame gameFrame) { //构造方法，设置UI，是为了区分多个客户端，我要是做游戏的话，就是通过 角色对象 区分
        this.gameFrame = gameFrame;
//        this.playerOther = playerOther;
        try {
            sc = new Socket(ip, 6666); //注意这个端口
            System.out.println("已顺利连接到服务器");
            in = new BufferedReader(new InputStreamReader(sc.getInputStream()));
            /**
             * 先实例化BufferedReader缓存流，再实例化InputStreamReader输入流，为了后续能通过readLine()方法一行一行的读数据
             * client.getInputStream() 是获取客户端socket的输入流
             */
            out = new PrintWriter(sc.getOutputStream(), true);
            /**
             * 实例化PrintWrite类 实现通过println()输出任意类型的数据
             * 可能对于游戏来说不太好，因为毕竟tcp协议传字节(byte)为主，他封装了一层，可能占用的空间增大很多
             * 但是也有好处，解决了拆包、粘包问题，就是不会字节没获取完就执行方法，因为读是通过in.readLine()一行一行的读的
             * 不过本身，拆包、粘包问题就不会很难解决，因为int、long等非字符串的字节数是固定的，加上条件判断即可
             * client.getOutputStream() 是获取客户端socket的输出流
             * autoFlush 默认自动确认输出，flush是是否输出
             */
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public int i = 0; //只执行一次的绘画判定

    public void run() {
        String msg = "";
        while (true) {
            try {
                msg = in.readLine(); //通过readLine()方法一行一行的读数据
            } catch (SocketException e) {
                System.out.println(e);
                break;
            } catch (Exception e) {
                System.out.println(e);
            }
            if (msg != null && msg.trim() != "") {
                String[] strs = msg.split(",");  //把字符串通过,分割开来

                System.out.println(">>" + msg);  //把从服务器获取的消息打印在控制台

                if (!(msg.contains("进入房间"))) {  //没有进入房间的操作
                    System.out.println(++i);
                    int playerId = Integer.valueOf(strs[0]); //用户id
                    int keyCode = Integer.valueOf(strs[1]);  //按键编号
                    String keyWay = strs[2]; //这个是判断是按下还是松开

                    PlayerOther nowPlayer = gameFrame.playerOtherList.get(playerId); //获取按下键盘的用户

                    if (keyWay.equals("released")) {  //按下事件  strs[2]
                        nowPlayer.keyReleased(keyCode);  //对应用户的按键操作
                    } else {
                        nowPlayer.keyPressed(keyCode);
                    }

                } else { //进入房间的操作
                    int sendId = Integer.valueOf(strs[0]);  //发送者的id  上面的strs
                    //判断该客户端是否已经存在 进入房间的用户

                    if (this.index == 0 && this.index != sendId) {  //判断是不是自己，因为默认是0，如果自己已经生成了，那就不是零,并且不等于发送的id
                        System.out.println("前index" + this.index);

                        this.index = sendId;

                        System.out.println("index" + this.index);
                        System.out.println("发送者的id" + sendId);

                    } else {
                        int j = 0;
                        for (Integer index : gameFrame.playerOtherList.keySet()) {
                            System.out.println("index" + index);
                            System.out.println("发送者的id" + sendId);

                            j++;  //最后一个还不在里面就发送进入房间

                            if (index == sendId) {
                                System.out.println("跳过");
                                j = 60;  //有一个相等直接变成60，这样的话，下面的j就不可能等于列表长度，因为60是列表的最大长度
                            } else {
                                System.out.println(j + "jjjjjjjjjjjj");

                                System.out.println(gameFrame.playerOtherList.size());
                                if (j == gameFrame.playerOtherList.size()) {
                                    this.sendMsg("进入房间");  //这个进入房间自己收不到？？？
                                    System.out.println("如果不是自己的话，就发送一个加入房间的消息");
                                }
                            }
                        }
                    }
                    PlayerOther player = new PlayerOther("src/main/resources/img/davis_0.png", gameFrame, sendId, "src/main/resources/img/davis_0.png", "src/main/resources/img/davis_1.png", "src/main/resources/img/davis_2.png", "src/main/resources/img/davis_0_mirror.png", "src/main/resources/img/davis_1_mirror.png", "src/main/resources/img/davis_2_mirror.png");
                    gameFrame.playerOtherList.put(sendId, player);

                }

            }
        }
    }

    public void sendMsg(String msg) {
        try {
            out.println(msg); //通过PrintWriter类的println()输出信息，然后通过socket线程判断，是否有新增输出信息，后渲染到UI
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
